//    |  /           |
//    ' /   __| _` | __|  _ \   __|
//    . \  |   (   | |   (   |\__ \.
//   _|\_\_|  \__,_|\__|\___/ ____/
//                   Multi-Physics
//
//  License:		 BSD License
//					 Kratos default license: kratos/license.txt
//
//  Main authors:    Bodhinanda Chandra, Ilaria Iaconeta
//
//


#if !defined(KRATOS_MPM_APPLICATION_VARIABLES_H_INCLUDED )
#define  KRATOS_MPM_APPLICATION_VARIABLES_H_INCLUDED

// Project includes
#include "includes/define.h"
#include "includes/constitutive_law.h"
#include "includes/variables.h"
#include "includes/deprecated_variables.h"
#include "includes/mat_variables.h"


namespace Kratos
{

    typedef array_1d<double,3> Vector3;
    typedef array_1d<double,6> Vector6;

    // Variables definition

    /* MATERIAL POINT ELEMENTS VARIABLES */
    // Indexing
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, int, MP_MATERIAL_ID )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, int, MATERIAL_POINTS_PER_ELEMENT )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, int, MP_SUB_POINTS)

    // Physical
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_MASS )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_DENSITY )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_VOLUME )
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, IS_COMPRESSIBLE)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, double, MP_TEMPERATURE)

    // Energy
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_POTENTIAL_ENERGY )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_KINETIC_ENERGY )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_STRAIN_ENERGY )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_TOTAL_ENERGY )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_TEMPERATURE)

    // Pressure
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_PRESSURE )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, PRESSURE_REACTION )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, NODAL_MPRESSURE )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, bool, IS_MIXED_FORMULATION )

    // Position and kinematics
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, MP_COORD )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, MP_DISPLACEMENT )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, MP_VELOCITY )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, MP_ACCELERATION )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, MP_VOLUME_ACCELERATION )

    // Stress Measures
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, Vector, MP_CAUCHY_STRESS_VECTOR )
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, double, MP_EQUIVALENT_STRESS)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, double, MP_HARDENING_RATIO)

    // Strain Measures
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, Vector, MP_ALMANSI_STRAIN_VECTOR )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_DELTA_PLASTIC_STRAIN )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_DELTA_PLASTIC_VOLUMETRIC_STRAIN )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_DELTA_PLASTIC_DEVIATORIC_STRAIN )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_EQUIVALENT_PLASTIC_STRAIN )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_EQUIVALENT_PLASTIC_STRAIN_RATE)
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_ACCUMULATED_PLASTIC_VOLUMETRIC_STRAIN )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MP_ACCUMULATED_PLASTIC_DEVIATORIC_STRAIN )

    // Constitutive law
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, ConstitutiveLaw::Pointer, CONSTITUTIVE_LAW_POINTER )
    // CL: Solid
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, RAYLEIGH_ALPHA )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, RAYLEIGH_BETA )
    // CL: Mohr Coulomb
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, COHESION )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, INTERNAL_DILATANCY_ANGLE )
    // CL: Mohr Coulomb Strain Softening
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, INTERNAL_FRICTION_ANGLE_RESIDUAL )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, COHESION_RESIDUAL )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, INTERNAL_DILATANCY_ANGLE_RESIDUAL )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, SHAPE_FUNCTION_BETA )
    // CL: Johnson Cook
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, REFERENCE_STRAIN_RATE)
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, TAYLOR_QUINNEY_COEFFICIENT)

    // Mesh variables
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, std::vector<typename Geometry<Node>::Pointer>, GEOMETRY_NEIGHBOURS)

    /* NODAL VARIABLES */
    // Conditions
    // Particle Conditions
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, MPC_COORD )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, int, MPC_CONDITION_ID )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, bool, MPC_IS_NEUMANN )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, MPC_AREA )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, MPC_NORMAL )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, MPC_DISPLACEMENT )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, MPC_DELTA_DISPLACEMENT )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, MPC_IMPOSED_DISPLACEMENT )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, MPC_VELOCITY )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, MPC_IMPOSED_VELOCITY )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, MPC_ACCELERATION )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, MPC_IMPOSED_ACCELERATION )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, MPC_CONTACT_FORCE )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, int, MATERIAL_POINTS_PER_CONDITION )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, bool, IS_EQUAL_DISTRIBUTED )
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, MPC_CALCULATE_NODAL_REACTIONS )
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, MPC_CALCULATE_CONTACT_FORCE )

    // Essential Boundary Conditions
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, double, PENALTY_FACTOR )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, int, MPC_BOUNDARY_CONDITION_TYPE )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, bool, PARTICLE_BASED_SLIP )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, WEIGHTED_VECTOR_RESIDUAL )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, Node::Pointer, MPC_LAGRANGE_NODE )
    KRATOS_DEFINE_APPLICATION_VARIABLE( MPM_APPLICATION, int, MP_COUNTER )

    // Natural Boundary Conditions
    // Nodal load variables
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS( MPM_APPLICATION, POINT_LOAD )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS( MPM_APPLICATION, LINE_LOAD )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS( MPM_APPLICATION, SURFACE_LOAD )

    // Momentum
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, NODAL_MOMENTUM )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, NODAL_INERTIA )
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS(MPM_APPLICATION, NODAL_INTERNAL_FORCE )

    // Solver related variables
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, IGNORE_GEOMETRIC_STIFFNESS)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, IS_AXISYMMETRIC)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, IS_PQMPM)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, IS_MAKE_NORMAL_MP_IF_PQMPM_FAILS)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, double, PQMPM_SUBPOINT_MIN_VOLUME_FRACTION)

    // Explicit time integration variables
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, CALCULATE_MUSL_VELOCITY_FIELD)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, IS_EXPLICIT)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, IS_EXPLICIT_CENTRAL_DIFFERENCE)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, int, EXPLICIT_STRESS_UPDATE_OPTION)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, CALCULATE_EXPLICIT_MP_STRESS)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, EXPLICIT_MAP_GRID_TO_MP)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, IS_FIX_EXPLICIT_MP_ON_GRID_EDGE)

    // Stabilization typedef
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, int, STABILIZATION_TYPE)

    // For friction
    KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS( MPM_APPLICATION, STICK_FORCE )
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, int, FRICTION_STATE)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, double, TANGENTIAL_PENALTY_FACTOR)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, FRICTION_ACTIVE)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, FRICTION_ASSIGNED)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, HAS_INITIAL_MOMENTUM)
    KRATOS_DEFINE_APPLICATION_VARIABLE(MPM_APPLICATION, bool, INITIAL_LOOP_COMPLETE)
}

#endif // KRATOS_MPM_APPLICATION_VARIABLES_H_INCLUDED  defined
